package com.ww.reactor.thread;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;

public class Reactor implements Runnable {

    final Selector selector;

    final ServerSocketChannel serverSocketChannel;

    Reactor(int port) throws IOException {
        selector = Selector.open();
        serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.socket().bind(new InetSocketAddress(port));
        serverSocketChannel.configureBlocking(false);
        SelectionKey sk = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); // 注册accept事件
        sk.attach(new Acceptor()); // 调用Acceptor()为回调方法
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) { // 循环
                selector.select();
                Set<SelectionKey> selectionKeys = selector.selectedKeys();
                Iterator<SelectionKey> it = selectionKeys.iterator();
                while (it.hasNext()) {
                    dispatch(it.next()); // dispatch分发事件
                }
                selectionKeys.clear();
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    void dispatch(SelectionKey k) {
        Runnable r = (Runnable) (k.attachment()); // 调用SelectionKey绑定调用对象
        if (null != r) {
            r.run();
        }
    }

    class Acceptor implements Runnable {

        @Override
        public void run() {
            try {
                SocketChannel accept = serverSocketChannel.accept();
                if (null != accept) {
                    new Handler(selector, accept);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}
